package com.yukefms.rule.formula;

import com.yukefms.common.ListTools;
import com.yukefms.engine.running.MatchedStatus;
import com.yukefms.engine.running.RunningContext;
import com.yukefms.jointpoint.BodyPointCloud;
import com.yukefms.rule.formula.interfaces.AbstractStaticBAFormula;
import com.yukefms.rule.formula.interfaces.DynamicBAFormula;
import com.yukefms.rule.formula.interfaces.StageBAFormula;
import com.yukefms.rule.formula.interfaces.StaticBAFormula;
import com.yukefms.rule.state.ActivatedState;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description  One type of CompositeStageBAFormula, i.e., Sequential StageBAFormula.
 * @Author Ping
 * @Date 2021/8/20 10:52
 **/
public class SeqStageBAFormula extends AbstractStaticBAFormula implements StageBAFormula {
    public static Logger logger = LogManager.getLogger(SeqStageBAFormula.class);
    private List<StageBAFormula> stageList ;
    private int curr = 0 ;
    private int size = 0 ;


    public SeqStageBAFormula() {
        this.stageList = new ArrayList<>() ;
    }
    public SeqStageBAFormula(List<StageBAFormula> stageList) {
        this.stageList = stageList;
        this.size = this.stageList.size() ;
        for (StageBAFormula stage : this.stageList) {
            ListTools.addAllNoDumplicate(this.jointTypes, stage.relatedJointTypes()) ;
        }
    }



    @Override
    public boolean hasNextStage() {
        return this.curr < this.size - 1;
    }

    @Override
    public StageBAFormula nextStage() {
        return this.stageList.get(++this.curr);
    }

    @Override
    public StageBAFormula currentStage() {
        return this.stageList.get(this.curr);
    }

    @Override
    public StageBAFormula add(StageBAFormula stage) {
        this.stageList.add(stage) ;
        this.size++ ;
        ListTools.addAllNoDumplicate(this.jointTypes, stage.relatedJointTypes());
        return this;
    }

    @Override
    public void reset() {
        this.curr = 0 ;
    }

    @Override
    public DynamicBAFormula dynamic() {
        return this.stageList.get(curr).dynamic();
    }

    @Override
    public StaticBAFormula response() {
        return this.stageList.get(curr).response();
    }
    @Override
    public MatchedStatus matched(BodyPointCloud bodyPointCloud, RunningContext context) {
        // note that, the response part in the current stage was considered.
        if (!this.hasNextStage()){
            logger.error("SeqStageBAFormula has not more stage.") ;
            return MatchedStatus.FALSE ;
        }
        return this.stageList.get(curr).matched(bodyPointCloud, context) ;
    }

}
